/***
	*******************************************************************************************************************************************************************
	* @file    gw_gray.c
	* @version V2.1
	* @date    2024-7-22
	* @author  御龙	
	* @brief   MSPM0G3507小车PID调试通用模板
   *************************************************************************************************
   *  @description
	*	
	*  适配感为灰度传感器，采用串行
   *
>>>>> 其他说明：未经允许不可擅自转发、售卖本套代码，大家都是我国的有为青年，请保持好自己的初心，在此，向你表达我的感谢
	*************************************************************************************************************************************************************
***/
#include "gw_gray.h"
#include "delay.h"

#define GW_GRAY_SERIAL_GPIO_GROUP 		Huidu_PORT
#define GW_GRAY_SERIAL_GPIO_CLK 		Huidu_CLK_PIN
#define GW_GRAY_SERIAL_GPIO_DAT 		Huidu_DAT_PIN



#define HuiDu_CLK_Clr()		DL_GPIO_clearPins(GW_GRAY_SERIAL_GPIO_GROUP, GW_GRAY_SERIAL_GPIO_CLK)
#define HuiDu_CLK_Set()		DL_GPIO_setPins(GW_GRAY_SERIAL_GPIO_GROUP, GW_GRAY_SERIAL_GPIO_CLK)

#define Read_HuiDu_DAT()	 ((DL_GPIO_readPins(GW_GRAY_SERIAL_GPIO_GROUP, GW_GRAY_SERIAL_GPIO_DAT)==GW_GRAY_SERIAL_GPIO_DAT)?0:1)

uint8_t Huidu_Datas;
#define GW_GRAY_DELAY_TICK 27

/* 8MHz 下5us大概是27 */
static void gw_gray_delay(uint32_t delay)
{
	volatile uint32_t delay_tick = delay;
	
	while (delay_tick > 0) {
		delay_tick--;
	}
}
uint8_t gw_gray_serial_read(void)
{
    uint8_t ret = 0;
    uint8_t i;
    for (i = 0; i < 8; ++i) {
        /* 输出时钟下降沿 */
        DL_GPIO_clearPins(GW_GRAY_SERIAL_GPIO_GROUP, GW_GRAY_SERIAL_GPIO_CLK);
        gw_gray_delay(GW_GRAY_DELAY_TICK); //有外部上拉源(4k ~ 10k电阻) 可不加此行

        /* 将读取的数据按相反顺序放入 ret */
        ret |= (Read_HuiDu_DAT() << (7 - i));

        /* 输出时钟上升沿,让传感器更新数据*/
        HuiDu_CLK_Set();
        /* 延迟需要在5us左右 */
        gw_gray_delay(GW_GRAY_DELAY_TICK);
    }
    return ret;
}
//uint8_t Huidu_Read(void)
//{
//	uint8_t Huidu_Data;
//	
//	for(int i=0;i<8;i++)
//	{
//		HuiDu_CLK_Clr();
//		delay_us(5);
//		Huidu_Data |= ((Read_HuiDu_DAT()) << i);
//		HuiDu_CLK_Set();
//		delay_us(5);
//	}
//	return Huidu_Data;
//}
float Huidu_Target = 0;
float Huidu_Error;
int Huidu_Sum;

float Huidu_Proc(uint8_t huidu_data)
{
	float huidu_error;
	static float huidu_lasterror;
	//---------------循迹部分开始--------------------//
	Huidu_Sum = 0;
	for(int i=0;i<8;i++)
	{
		if((huidu_data>>i)&0x01) Huidu_Sum++;
	}
	if(Huidu_Sum<=3)//在巡线
	{
		switch(huidu_data)
		{
			//无误差
			case 0x18:// 0001 1000
			{
				Huidu_Error = 0;
			}break;
			//-------------------------
			case 0x10:// 0001 0000
			{
				Huidu_Error = 1;
			}break;
			case 0x30:// 0011 0000
			{
				Huidu_Error = 2;
			}break;
			case 0x20:// 0010 0000
			{
				Huidu_Error = 3;
			}break;
			case 0x60:// 0110 0000
			{
				Huidu_Error = 4;
			}break;
			case 0x40:// 0100 0000
			{
				Huidu_Error = 5;
			}break;
			case 0xc0:// 1100 0000
			{
				Huidu_Error = 6;
			}break;
			case 0x80:// 1000 0000
			{
				Huidu_Error = 7;
			}break;
			//-------------------------
			case 0x08:// 0000 1000
			{
				Huidu_Error = -1;
			}break;
			case 0x0c:// 0000 1100
			{
				Huidu_Error = -2;
			}break;
			case 0x04:// 0000 0100
			{
				Huidu_Error = -3;
			}break;
			case 0x06:// 0000 0110
			{
				Huidu_Error = -4;
			}break;
			case 0x02:// 0000 0010
			{
				Huidu_Error = -5;
			}break;
			case 0x03:// 0000 0011
			{
				Huidu_Error = -6;
			}break;
			case 0x01:// 0000 0001
			{
				Huidu_Error = -7;
			}break;
			default://如果没有符合的就保持上一次的误差
			{
				Huidu_Error = huidu_lasterror;
			}break;
		}
	}
	else if(Huidu_Sum>3&&Huidu_Sum<=5)//转直角弯
	{Huidu_Error=0;
		
	}
	else//停车或转180
	{Huidu_Error=0;
		//Basic_Speed = 0;
	}
	
	huidu_error = Huidu_Error;
	//记录当前误差
	huidu_lasterror = huidu_error;
	return huidu_error;
}


